package org.yeasy.report.util;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.date.DateException;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import com.alibaba.fastjson.JSONObject;
import org.yeasy.common.util.CommonBeanUtil;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * The type My bean util.bean的处理工具.
 * 大致而言,支持两种类型:
 * 1. bean类型,但需要确保实现了序列化
 * 2. fastjson对象
 *
 * @author yangyishe
 * @date 2022年08月31日 14:55
 */
public class ReportBeanUtil {


    /**
     * Merge object t.合并对象
     *
     * @param <T>    the type parameter
     * @param target the target
     * @param source the source
     * @return the t
     * @author yangyishe
     * @date 2022年09月01日 17:58
     */
    public static <T extends Serializable> T mergeObject(T target, T source) {
        T mNewTarget = ObjectUtil.clone(target);
        if (target.getClass() == JSONObject.class) {
            JSONObject mSource = (JSONObject) source;
            JSONObject mTarget = (JSONObject) mNewTarget;
            for (Map.Entry<String, Object> field2Val : mSource.entrySet()) {
                String strField = field2Val.getKey();
                Object mValue = field2Val.getValue();
                mTarget.putIfAbsent(strField, mValue);
            }
        } else {
            BeanUtil.copyProperties(source, mNewTarget, CopyOptions.create().ignoreNullValue());
        }
        return mNewTarget;
    }



    /**
     * Reset decimal value.重置所有的decimal值.->仅适用普通bean
     * 主要用于重置混合基底数据用
     *
     * @param <T> the type parameter
     * @param t   the t
     * @author yangyishe
     * @date 2022年09月05日 16:21
     */
    public static <T extends Serializable> void resetDecimalValue(T t) {
        Field[] arrAllField = t.getClass().getDeclaredFields();
        List<String> lstDecimalField = Arrays.stream(arrAllField).filter(o -> o.getType() == BigDecimal.class).map(Field::getName).collect(Collectors.toList());
        for (String decimalField : lstDecimalField) {
            CommonBeanUtil.invokeSetter(t, decimalField, BigDecimal.ZERO);
        }
    }

    /**
     * Fill null default decimal value.空值填充0->仅适用普通bean
     *
     * @param <T> the type parameter
     * @param t   the t
     * @author yangyishe
     * @date 2022年09月05日 16:48
     */
    public static <T extends Serializable> void resetDecimalValueIfNull(T t) {
        Field[] arrAllField = t.getClass().getDeclaredFields();
        List<String> lstDecimalField = Arrays.stream(arrAllField).filter(o -> o.getType() == BigDecimal.class).map(Field::getName).collect(Collectors.toList());
        for (String decimalField : lstDecimalField) {
            if (CommonBeanUtil.invokeGetter(t, decimalField) == null) {
                CommonBeanUtil.invokeSetter(t, decimalField, BigDecimal.ZERO);
            }
        }
    }


}
